home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / include / glibmm-2.4 / glibmm / listhandle.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-04-20  |  10.5 KB  |  407 lines

  1. // -*- c++ -*-
  2. #ifndef _GLIBMM_LISTHANDLE_H
  3. #define _GLIBMM_LISTHANDLE_H
  4.  
  5. /* $Id: listhandle.h,v 1.3 2003/04/21 17:39:41 murrayc Exp $ */
  6.  
  7. /* Copyright (C) 2002 The gtkmm Development Team
  8.  *
  9.  * This library is free software; you can redistribute it and/or
  10.  * modify it under the terms of the GNU Library General Public
  11.  * License as published by the Free Software Foundation; either
  12.  * version 2 of the License, or (at your option) any later version.
  13.  *
  14.  * This library is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17.  * Library General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU Library General Public
  20.  * License along with this library; if not, write to the Free
  21.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  */
  23.  
  24. #include <glib/glist.h>
  25. #include <glibmm/containerhandle_shared.h>
  26.  
  27.  
  28. namespace Glib
  29. {
  30.  
  31. namespace Container_Helpers
  32. {
  33.  
  34. #ifndef DOXYGEN_SHOULD_SKIP_THIS
  35.  
  36. /* Create and fill a GList as efficient as possible.
  37.  * This requires bidirectional iterators.
  38.  */
  39. template <class Bi, class Tr>
  40. GList* create_list(Bi pbegin, Bi pend, Tr)
  41. {
  42.   GList* head = 0;
  43.  
  44.   while(pend != pbegin)
  45.   {
  46.     // Use & to force a warning if the iterator returns a temporary object.
  47.     const void *const item = Tr::to_c_type(*&*--pend);
  48.     head = g_list_prepend(head, const_cast<void*>(item));
  49.   }
  50.  
  51.   return head;
  52. }
  53.  
  54. /* Create a GList from a 0-terminated input sequence.
  55.  * Build it in reverse order and reverse the whole list afterwards,
  56.  * because appending to the list would be horribly inefficient.
  57.  */
  58. template <class For, class Tr>
  59. GList* create_list(For pbegin, Tr)
  60. {
  61.   GList* head = 0;
  62.  
  63.   while(*pbegin)
  64.   {
  65.     // Use & to force a warning if the iterator returns a temporary object.
  66.     const void *const item = Tr::to_c_type(*&*pbegin);
  67.     head = g_list_prepend(head, const_cast<void*>(item));
  68.     ++pbegin;
  69.   }
  70.  
  71.   return g_list_reverse(head);
  72. }
  73.  
  74.  
  75. /* Convert from any container that supports bidirectional iterators.
  76.  */
  77. template <class Tr, class Cont>
  78. struct ListSourceTraits
  79. {
  80.   static GList* get_data(const Cont& cont)
  81.     { return Glib::Container_Helpers::create_list(cont.begin(), cont.end(), Tr()); }
  82.  
  83.   static const Glib::OwnershipType initial_ownership = Glib::OWNERSHIP_SHALLOW;
  84. };
  85.  
  86. /* Convert from a 0-terminated array.  The Cont
  87.  * argument must be a pointer to the first element.
  88.  */
  89. template <class Tr, class Cont>
  90. struct ListSourceTraits<Tr,Cont*>
  91. {
  92.   static GList* get_data(const Cont* array)
  93.     { return (array) ? Glib::Container_Helpers::create_list(array, Tr()) : 0; }
  94.  
  95.   static const Glib::OwnershipType initial_ownership = Glib::OWNERSHIP_SHALLOW;
  96. };
  97.  
  98. template <class Tr, class Cont>
  99. struct ListSourceTraits<Tr,const Cont*> : ListSourceTraits<Tr,Cont*>
  100. {};
  101.  
  102. /* Convert from a 0-terminated array.  The Cont argument must be a pointer
  103.  * to the first element.  For consistency, the array must be 0-terminated,
  104.  * even though the array size is known at compile time.
  105.  */
  106. template <class Tr, class Cont, size_t N>
  107. struct ListSourceTraits<Tr,Cont[N]>
  108. {
  109.   static GList* get_data(const Cont* array)
  110.     { return Glib::Container_Helpers::create_list(array, array + (N - 1), Tr()); }
  111.  
  112.   static const Glib::OwnershipType initial_ownership = Glib::OWNERSHIP_SHALLOW;
  113. };
  114.  
  115. template <class Tr, class Cont, size_t N>
  116. struct ListSourceTraits<Tr,const Cont[N]> : ListSourceTraits<Tr,Cont[N]>
  117. {};
  118.  
  119. #endif /* DOXYGEN_SHOULD_SKIP_THIS */
  120.  
  121.  
  122. /**
  123.  * @ingroup ContHelpers
  124.  * If a method takes this as an argument, or has this as a return type, then you can use a standard
  125.  * container such as std::list or std::vector.
  126.  */
  127. template <class Tr>
  128. class ListHandleIterator
  129. {
  130. public:
  131.   typedef typename Tr::CppType        CppType;
  132.   typedef typename Tr::CType          CType;
  133.  
  134.   typedef std::forward_iterator_tag   iterator_category;
  135.   typedef CppType                     value_type;
  136.   typedef ptrdiff_t                   difference_type;
  137.   typedef value_type                  reference;
  138.   typedef void                        pointer;
  139.  
  140.   explicit inline ListHandleIterator(const GList* node);
  141.  
  142.   inline value_type                   operator*() const;
  143.   inline ListHandleIterator<Tr> &     operator++();
  144.   inline const ListHandleIterator<Tr> operator++(int);
  145.  
  146.   inline bool operator==(const ListHandleIterator<Tr>& rhs) const;
  147.   inline bool operator!=(const ListHandleIterator<Tr>& rhs) const;
  148.  
  149. private:
  150.   const GList* node_;
  151. };
  152.  
  153. } // namespace Container_Helpers
  154.  
  155.  
  156. /**
  157.  * @ingroup ContHandles
  158.  */
  159. template < class T, class Tr = Glib::Container_Helpers::TypeTraits<T> >
  160. class ListHandle
  161. {
  162. public:
  163.   typedef typename Tr::CppType  CppType;
  164.   typedef typename Tr::CType    CType;
  165.  
  166.   typedef CppType               value_type;
  167.   typedef size_t                size_type;
  168.   typedef ptrdiff_t             difference_type;
  169.  
  170.   typedef Glib::Container_Helpers::ListHandleIterator<Tr>  const_iterator;
  171.   typedef Glib::Container_Helpers::ListHandleIterator<Tr>  iterator;
  172.  
  173.   template <class Cont> inline
  174.     ListHandle(const Cont& container);
  175.  
  176.   // Take over ownership of an array created by GTK+ functions.
  177.   inline ListHandle(GList* glist, Glib::OwnershipType ownership);
  178.  
  179.   // Copying clears the ownership flag of the source handle.
  180.   inline ListHandle(const ListHandle<T,Tr>& other);
  181.  
  182.   ~ListHandle();
  183.  
  184.   inline const_iterator begin() const;
  185.   inline const_iterator end()   const;
  186.  
  187.   template <class U> inline operator std::vector<U>() const;
  188.   template <class U> inline operator std::deque<U>()  const;
  189.   template <class U> inline operator std::list<U>()   const;
  190.  
  191.   template <class Cont> inline
  192.     void assign_to(Cont& container) const;
  193.  
  194.   template <class Out> inline
  195.     void copy(Out pdest) const;
  196.  
  197.   inline GList* data()  const;
  198.   inline size_t size()  const;
  199.   inline bool   empty() const;
  200.  
  201. private:
  202.   GList *                     plist_;
  203.   mutable Glib::OwnershipType ownership_;
  204.  
  205.   // No copy assignment.
  206.   ListHandle<T,Tr>& operator=(const ListHandle<T,Tr>&);
  207. };
  208.  
  209.  
  210. /***************************************************************************/
  211. /*  Inline implementation                                                  */
  212. /***************************************************************************/
  213.  
  214. #ifndef DOXYGEN_SHOULD_SKIP_THIS
  215.  
  216. namespace Container_Helpers
  217. {
  218.  
  219. /**** Glib::Container_Helpers::ListHandleIterator<> ************************/
  220.  
  221. template <class Tr> inline
  222. ListHandleIterator<Tr>::ListHandleIterator(const GList* node)
  223. :
  224.   node_ (node)
  225. {}
  226.  
  227. template <class Tr> inline
  228. typename ListHandleIterator<Tr>::value_type ListHandleIterator<Tr>::operator*() const
  229. {
  230.   return Tr::to_cpp_type(static_cast<typename Tr::CTypeNonConst>(node_->data));
  231. }
  232.  
  233. template <class Tr> inline
  234. ListHandleIterator<Tr>& ListHandleIterator<Tr>::operator++()
  235. {
  236.   node_ = node_->next;
  237.   return *this;
  238. }
  239.  
  240. template <class Tr> inline
  241. const ListHandleIterator<Tr> ListHandleIterator<Tr>::operator++(int)
  242. {
  243.   const ListHandleIterator<Tr> tmp (*this);
  244.   node_ = node_->next;
  245.   return tmp;
  246. }
  247.  
  248. template <class Tr> inline
  249. bool ListHandleIterator<Tr>::operator==(const ListHandleIterator<Tr>& rhs) const
  250. {
  251.   return (node_ == rhs.node_);
  252. }
  253.  
  254. template <class Tr> inline
  255. bool ListHandleIterator<Tr>::operator!=(const ListHandleIterator<Tr>& rhs) const
  256. {
  257.   return (node_ != rhs.node_);
  258. }
  259.  
  260. } // namespace Container_Helpers
  261.  
  262.  
  263. /**** Glib::ListHandle<> ***************************************************/
  264.  
  265. template <class T, class Tr>
  266.   template <class Cont>
  267. inline
  268. ListHandle<T,Tr>::ListHandle(const Cont& container)
  269. :
  270.   plist_     (Glib::Container_Helpers::ListSourceTraits<Tr,Cont>::get_data(container)),
  271.   ownership_ (Glib::Container_Helpers::ListSourceTraits<Tr,Cont>::initial_ownership)
  272. {}
  273.  
  274. template <class T, class Tr> inline
  275. ListHandle<T,Tr>::ListHandle(GList* glist, Glib::OwnershipType ownership)
  276. :
  277.   plist_     (glist),
  278.   ownership_ (ownership)
  279. {}
  280.  
  281. template <class T, class Tr> inline
  282. ListHandle<T,Tr>::ListHandle(const ListHandle<T,Tr>& other)
  283. :
  284.   plist_     (other.plist_),
  285.   ownership_ (other.ownership_)
  286. {
  287.   other.ownership_ = Glib::OWNERSHIP_NONE;
  288. }
  289.  
  290. template <class T, class Tr>
  291. ListHandle<T,Tr>::~ListHandle()
  292. {
  293.   if(ownership_ != Glib::OWNERSHIP_NONE)
  294.   {
  295.     if(ownership_ != Glib::OWNERSHIP_SHALLOW)
  296.     {
  297.       // Deep ownership: release each container element.
  298.       for(GList* node = plist_; node != 0; node = node->next)
  299.         Tr::release_c_type(static_cast<typename Tr::CTypeNonConst>(node->data));
  300.     }
  301.     g_list_free(plist_);
  302.   }
  303. }
  304.  
  305. template <class T, class Tr> inline
  306. typename ListHandle<T,Tr>::const_iterator ListHandle<T,Tr>::begin() const
  307. {
  308.   return Glib::Container_Helpers::ListHandleIterator<Tr>(plist_);
  309. }
  310.  
  311. template <class T, class Tr> inline
  312. typename ListHandle<T,Tr>::const_iterator ListHandle<T,Tr>::end() const
  313. {
  314.   return Glib::Container_Helpers::ListHandleIterator<Tr>(0);
  315. }
  316.  
  317. template <class T, class Tr>
  318.   template <class U>
  319. inline
  320. ListHandle<T,Tr>::operator std::vector<U>() const
  321. {
  322. #ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
  323.   return std::vector<U>(this->begin(), this->end());
  324. #else
  325.   std::vector<U> temp;
  326.   temp.reserve(this->size());
  327.   Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
  328.   return temp;
  329. #endif
  330. }
  331.  
  332. template <class T, class Tr>
  333.   template <class U>
  334. inline
  335. ListHandle<T,Tr>::operator std::deque<U>() const
  336. {
  337. #ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
  338.   return std::deque<U>(this->begin(), this->end());
  339. #else
  340.   std::deque<U> temp;
  341.   Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
  342.   return temp;
  343. #endif
  344. }
  345.  
  346. template <class T, class Tr>
  347.   template <class U>
  348. inline
  349. ListHandle<T,Tr>::operator std::list<U>() const
  350. {
  351. #ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
  352.   return std::list<U>(this->begin(), this->end());
  353. #else
  354.   std::list<U> temp;
  355.   Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
  356.   return temp;
  357. #endif
  358. }
  359.  
  360. template <class T, class Tr>
  361.   template <class Cont>
  362. inline
  363. void ListHandle<T,Tr>::assign_to(Cont& container) const
  364. {
  365. #ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
  366.   container.assign(this->begin(), this->end());
  367. #else
  368.   Cont temp;
  369.   Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
  370.   container.swap(temp);
  371. #endif
  372. }
  373.  
  374. template <class T, class Tr>
  375.   template <class Out>
  376. inline
  377. void ListHandle<T,Tr>::copy(Out pdest) const
  378. {
  379.   std::copy(this->begin(), this->end(), pdest);
  380. }
  381.  
  382. template <class T, class Tr> inline
  383. GList* ListHandle<T,Tr>::data() const
  384. {
  385.   return plist_;
  386. }
  387.  
  388. template <class T, class Tr> inline
  389. size_t ListHandle<T,Tr>::size() const
  390. {
  391.   return g_list_length(plist_);
  392. }
  393.  
  394. template <class T, class Tr> inline
  395. bool ListHandle<T,Tr>::empty() const
  396. {
  397.   return (plist_ == 0);
  398. }
  399.  
  400. #endif /* DOXYGEN_SHOULD_SKIP_THIS */
  401.  
  402. } // namespace Glib
  403.  
  404.  
  405. #endif /* _GLIBMM_LISTHANDLE_H */
  406.  
  407.